package com.cloudkinto.service.platform.shopList;

import cn.afterturn.easypoi.csv.entity.CsvExportParams;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.RabbitQueueConstant;
import com.cloudkinto.common.RedisKeyConstants;
import com.cloudkinto.common.common.DateUtils;
import com.cloudkinto.common.utils.CsvUtils;
import com.cloudkinto.common.utils.SuperDeliveryUtil;
import com.cloudkinto.common.utils.ali.AliOss;
import com.cloudkinto.common.utils.dict.StaticDict;
import com.cloudkinto.dao.AsyncJobDao;
import com.cloudkinto.dao.PlatformOrderDao;
import com.cloudkinto.dao.PlatformStoreDao;
import com.cloudkinto.dao.ProductStockDao;
import com.cloudkinto.entity.AsyncJobDo;
import com.cloudkinto.entity.PlatformOrderDo;
import com.cloudkinto.entity.PlatformProductDo;
import com.cloudkinto.entity.PlatformStoreDo;
import com.cloudkinto.service.consumer.vo.StockToPlatformConsumerReq;
import com.cloudkinto.service.platform.shopList.vo.HeaderEntity;
import com.cloudkinto.service.platform.shopList.vo.ProductSetEntity;
import com.cloudkinto.service.platform.shopList.vo.ProductSetReq;
import com.cloudkinto.service.platform.shopList.vo.ProductSetSearchEntity;
import com.cloudkinto.service.platform.shopList.vo.stockUpdate.DetailResultEntity;
import com.cloudkinto.service.platform.vo.AsyncFinishConsumerReq;
import com.cloudkinto.service.platform.vo.AsyncUpdateConsumerReq;
import com.cloudkinto.service.platform.vo.StockToPlatformRecordVo;
import com.cloudkinto.service.platform.vo.rakuten.PlatformProductSyncReq;
import com.cloudkinto.vo.stock.PlatformSkuStockDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
@Slf4j
@RequiredArgsConstructor
public class PlatformOrderSuperDeliverySyncServiceImpl extends ServiceImpl<PlatformOrderDao, PlatformOrderDo> implements PlatformOrderSuperDeliverySyncService {
    @Value("${gbc.customer}")
    private String customer;
    private final RedisTemplate redisTemplate;
    private final RabbitTemplate rabbitTemplate;
    @Value("${gbc.exportPath.omsFilePath}")
    private String omsFilePath;
    @Value("${gbc.uploadPath.omsFileUrl}")
    private String omsFileUrl;
    @Value("${gbc.uploadPath.fileUrl}")
    private String fileUrl;
    @Value("${gbc.uploadPath.filePath}")
    private String filePath;
    private final PlatformStoreDao platformStoreDao;
    private final AsyncJobDao asyncJobDao;
    private final ProductStockDao productStockDao;



    @Override
    public String productSetSearch(PlatformStoreDo storeDo) {
        if (storeDo == null || StringUtils.isBlank(storeDo.getAppKey())) {
            return ("店铺未授权");
        }
        String key = RedisKeyConstants.PlatformProduct_Sync_Flag_ +customer+ storeDo.getId();
        Object o = redisTemplate.opsForValue().get(key);
        if (o != null) {
            return storeDo.getStoreCode() + " 正在同步商品";
        }
        redisTemplate.opsForValue().set(key, 1, 20, TimeUnit.MINUTES);
        //■限制事项
        //输出上限：10000集/请求
        //访问限制：10个请求/10分钟
        //※超过输出上限的部分不输出。（最多输出10000组）
        //※超过访问限制的请求会出错，不会进行处理。
        String url = "https://www.superdelivery.com/q/merchandise/ProductSetSearch/ver1.0/g.json?" +
                "apiAuthCode=" + storeDo.getAppSecret() +
                "&field=stock,exhibitState,janCode";
        Map<String, Object> param = new HashMap<>();
        String body = null;
        try {
            body = SuperDeliveryUtil.raAPidoGet(url, param);
        } catch (Exception e) {
            return e.getMessage();
        }
        if (StringUtils.isBlank(body)) {
            return "连接超时";
        }
        JSONObject jsonObject = JSONObject.parseObject(body);
        JSONObject header = jsonObject.getJSONObject("header");
        if (header == null) {
            return "同步商品失败：header 不存在";
        }
        String status = header.getString("status");
        if (!Objects.equals("SUCCESS", status)) {
            return "同步商品失败：" + status +" | " + header.getString("message");
        }
        JSONObject productSets = jsonObject.getJSONObject("body").getJSONObject("productSets");
        if (productSets == null) {
            return "同步商品失败：productSets 不存在";
        }
        List<ProductSetSearchEntity> productSetSearchEntityList = JSONObject.parseArray(productSets.getString("productSet"), ProductSetSearchEntity.class);
        for (ProductSetSearchEntity searchEntity : productSetSearchEntityList) {
            PlatformProductDo productDo = new PlatformProductDo();
            //todo
        }
//        Map<String, List<PlatformProductDo>> parentSkuMap = productDoList.stream().filter(i -> StringUtils.isNotBlank(i.getParentSku())).collect(Collectors.groupingBy(PlatformProductDo::getParentSku));
//        boolean delete = org.apache.commons.lang3.StringUtils.isBlank(platformSku);
//        for (String parentSkuKey : parentSkuMap.keySet()) {
//            rabbitTemplate.convertAndSend(RabbitQueueConstant.PlatformProduct_Rakuten_UpdateByParentSKu, JSON.toJSONString(new PlatformProductSyncReq(parentSkuMap.get(parentSkuKey),
//                    StaticDict.Store_PlatformCode.Rakuten.getValue(), delete, storeDo.getId(), storeDo.getCompanyId())));
//        }
        return null;
    }


    /**
     * 输入上限：5000个/请求  10000件/小时※超过上限的部分为错误，不进行处理。例.输入有6000件的情况下，处理到5000件，从第5001件开始全部为错误
     */
    @Override
    public void setStockByStoreId(StockToPlatformConsumerReq req) {
        PlatformStoreDo storeDo = platformStoreDao.selectById(req.getStoreId());
        if (storeDo == null) {
            return;
        }
        AsyncJobDo asyncJobDo = asyncJobDao.selectById(req.getJobId());
        if (asyncJobDo == null) {
            return;
        }
        //告诉他正在处理
        rabbitTemplate.convertAndSend(RabbitQueueConstant.Export_AsyncDo_Update, JSON.toJSONString(new AsyncUpdateConsumerReq(req.getJobId(), 1, 0, null)));
        List<PlatformSkuStockDto> skuStockList = productStockDao.getPlatformSkuStockList(Arrays.asList(StaticDict.Store_PlatformCode.Rakuten.getValue()),
                req.getPlatformSkuList(), null, req.getInventoryLink(), Arrays.asList(req.getStoreId()));
        if (skuStockList.isEmpty()) {
            rabbitTemplate.convertAndSend(RabbitQueueConstant.Export_AsyncDo_Finish, JSON.toJSONString(new AsyncFinishConsumerReq(req.getJobId(), null)));
            return;
        }
        List<ProductSetReq> stockList = new ArrayList<>();
        for (PlatformSkuStockDto skuStock : skuStockList) {
//            if (skuStock.getSystemProductId() == null) {
//                continue;
//            }
//            if (org.apache.commons.lang.StringUtils.isBlank(skuStock.getParentSku())) {
//                continue;
//            }
            if (req.getUserId() == null && skuStock.getHideItem() != null && skuStock.getHideItem() == 1) {
                continue;
            }
            double stockPercent = skuStock.getStockPercent() < 0 || skuStock.getStockPercent() > 1 ? 0.95 : 1 - skuStock.getStockPercent();
            int quantity = (int) (skuStock.getLeftQty() / skuStock.getQty() * stockPercent);
            quantity = Math.min(Math.max(quantity, 0), 99999);
            stockList.add(new ProductSetReq(skuStock.getId(), skuStock.getParentSku(), skuStock.getPlatformSku(), quantity));
        }

        try {
            String key = asyncJobDo.getJobType() + "_count_"  + "_" + asyncJobDo.getCompanyId() + "_" + customer + "_" + DateUtils.dateFormatToString(new Date(), "yyyyMMdd");
            long count = redisTemplate.opsForValue().increment(key, 1);
            redisTemplate.expire(key, 60 * 60 * 25, TimeUnit.SECONDS);
            String fileName = asyncJobDo.getJobName() + "_" + count + ".csv";
            String tempFilePath = omsFilePath + fileName;
            CsvExportParams csvParam = new CsvExportParams();
//            csvParam.setEncoding("Shift-JIS");
            csvParam.setEncoding("UTF-8");
            csvParam.setTextMark("");
            CsvUtils.initCsv(tempFilePath, csvParam, StockToPlatformRecordVo.class);
            List<List<ProductSetReq>> partition = ListUtil.partition(stockList, 1000);
            String url = "https://www.superdelivery.com/q/merchandise/StockUpdate/dealerProductCode/ver1.0/p.json";
//            String contentType = "application/json; charset=UTF-8";
            String ContentLength = "100";
            for (List<ProductSetReq> inventoryRakutenEntities : partition) {
                List<ProductSetEntity> productSet = inventoryRakutenEntities.stream().filter(i -> StringUtils.isNotBlank(i.getDealerProductCode())).map(i -> new ProductSetEntity(i.getDealerProductCode(), i.getStock())).collect(Collectors.toList());

                JSONObject param = new JSONObject();
                JSONObject productSets = new JSONObject();
                productSets.put("productSet", productSet);
                param.put("body", productSets);
                param.put("header", new HeaderEntity(storeDo.getAppSecret()));
                String body = SuperDeliveryUtil.raAPidoPOST(url, param);
                String error = null;
                Map<String, String> failMap = new HashMap<>();
                if (StringUtils.isBlank(body)) {
                    error = "连接超时";
                }
                else {
                    JSONObject jsonObject = JSONObject.parseObject(body);
                    JSONObject header = jsonObject.getJSONObject("header");
                    if (header == null) {
                       error = "header 不存在";
                    }
                    else {
                        String status = header.getString("status");
                        String message = header.getString("message");
                        if (!Objects.equals("SUCCESS", status) && StringUtils.isNotBlank(message)) {
                            error = status + " | " + message;
                        }
                        else {
                            JSONObject detailResults = jsonObject.getJSONObject("body").getJSONObject("detailResults");
                            if (detailResults == null) {
                                error = "detailResults 不存在";
                            }
                            else {
                                List<DetailResultEntity> entities = JSONObject.parseArray(productSets.getString("detailResult"), DetailResultEntity.class);
                                //分析成功 还是失败
                                for (DetailResultEntity entity : entities) {
                                    if ("SUCCESS".equals(entity.getStatus())) {
                                        continue;
                                    }
                                    entity.getCodeMessages().getCodeMessage().forEach(i -> failMap.put(i.getCode().getDealerProductCode(), i.getMessage()));
                                }

                            }
                        }
                    }
                }
                List<StockToPlatformRecordVo> list = new ArrayList<>();
                for (ProductSetReq inventoryRakutenEntity : inventoryRakutenEntities) {
                    String errorMsg = failMap.get(inventoryRakutenEntity.getDealerProductCode());
                    if (StringUtils.isBlank(error) && StringUtils.isBlank(errorMsg)) {
                        //成功
                        list.add(new StockToPlatformRecordVo(inventoryRakutenEntity.getParentSku(), inventoryRakutenEntity.getDealerProductCode(), inventoryRakutenEntity.getStock(), "成功", null));
                    } else {
                        errorMsg = errorMsg == null ? "" : errorMsg;
                        list.add(new StockToPlatformRecordVo(inventoryRakutenEntity.getParentSku(), inventoryRakutenEntity.getDealerProductCode(), inventoryRakutenEntity.getStock(), "失败", error + errorMsg));
                    }
                }
                CsvUtils.appendToCsv(tempFilePath, list);
                rabbitTemplate.convertAndSend(RabbitQueueConstant.Export_AsyncDo_Update, JSON.toJSONString(new AsyncUpdateConsumerReq(req.getJobId(), null, list.size(), null)));
                Thread.sleep(1500);
            }
            //本机文件传到oms上
            String objectNameTemporary = "";
            if (filePath.startsWith("http")) {
                try {
                    objectNameTemporary = AliOss.temporaryFile2(fileName, new File(tempFilePath));
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("导出文件失败" + e.getMessage());
                }
            }
            //文件路径
            String path = fileUrl + objectNameTemporary;
            rabbitTemplate.convertAndSend(RabbitQueueConstant.Export_AsyncDo_Finish, JSON.toJSONString(new AsyncFinishConsumerReq(req.getJobId(), path)));
        } catch (Exception e) {
            e.printStackTrace();
            rabbitTemplate.convertAndSend(RabbitQueueConstant.Export_AsyncDo_Update, JSON.toJSONString(new AsyncUpdateConsumerReq(req.getJobId(), 4, 0, e.getMessage())));
        }
    }


}
